<?php

namespace Biz\service\activity\project;

use AlibabaCloud\SDK\OSS\OSS\GetBucketWebsiteResponse\websiteConfiguration\routingRules\routingRule\redirect\mirrorHeaders\set;
use Biz\model\activity\BizProjectFieldAuthModel;
use Biz\model\activity\BizProjectGroupModel;
use Biz\model\activity\BizProjectResponsibilityModel;
use Doraemon\model\Admin\BeerUsUser;
use Encore\Admin\Grid;
use Encore\Admin\Widgets\Form;
use Exception;

class BizProjectGroup extends BizProjectPageTpl
{

    const TPL_CONFIG_TPL_NAME = '项目责任方权限';


    public function getList(): array
    {
        $condition = ['ORDER' => ['id' => 'DESC'], 'LIMIT' => [$this->getOffset(), $this->getPageSize()]];
        $list = BizProjectGroupModel::dataSelect($condition + ['group_id' => 0] + BizProjectGroupModel::statusCondition());
        $members = BizProjectGroupModel::dataSelect(['group_id[!]' => 0] + BizProjectGroupModel::statusCondition());
        $response = [];
        if ($list) {
            $admin_ids = array_column($list, 'admin_id');
            $admin_ids = array_merge(array_column($members, 'admin_id'), $admin_ids);
            BeerUsUser::getNameByUsername($this->uniqueFilter($admin_ids));
            $membersMap = [];
            foreach ($members as $v) {
                $membersMap[$v['group_id']][] = $v['admin_id'];
            }
            foreach ($list as $v) {
                $response[] = [
                    'id' => $v['id'],
                    'name' => $v['name'],
                    'responsible' => $v['responsible'],
                    'email' => $v['email'],
                    'leader' => BeerUsUser::afterGetRowsMap($v['admin_id']),
                    'member' => BeerUsUser::afterGetRowsMap($membersMap[$v['id']]),
                    'created_at_date' => $v['created_at'],
                ];
            }
        }
        return $response;
    }

    public function getTotal(): int
    {
        return BizProjectGroupModel::statusTotal($this->getRequestCondition() + BizProjectGroupModel::statusCondition() + ['group_id' => 0]);
    }

    public function getGrid(Grid $grid)
    {
        $grid->disableFilter();
        $grid->column('id', 'ID');
        $grid->column('responsible', '项目责任方')->using(BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_TITLE_MAP);
        $grid->column('name', '组名称');
        $grid->column('leader', '组长')->label('warning');
        $grid->column('email', '组长邮箱');
        $grid->column('member', '组员')->label();
        $grid->column('created_at_date', '创建时间');
        $grid->actions(function (Grid\Displayers\Actions $actions) {
            $actions->disableView();
        });
    }

    public function getForm(Form $form)
    {
        $nameOptions = BeerUsUser::getActiveNameByIds();
        $auths = $this->optionsAuth();
        $form->select('responsible', '项目责任方')->options(BizProjectResponsibilityModel::RESPONSIBILITY_TYPE_TITLE_MAP)->default(-1);
        $form->text('name', '组名称')->required();
        $form->select('leader_id', '组长')->options($nameOptions)->required();
        $form->email('email', '组长邮箱')->required();
        $form->multipleSelect('member', '组员')->options($nameOptions);
        $form->listbox('master_auth', '组长权限')->options($auths);
        $form->listbox('member_auth', '组员权限/项目责任方权限')->options($auths);
    }

    public function getFormInfo($id): array
    {
        $info = $id ? BizProjectGroupModel::dataSelect(['OR' => ['id' => $id, 'group_id' => $id]] + BizProjectGroupModel::statusCondition()) : [];
        $fieldAuth = $id ? BizProjectFieldAuthModel::dataSelect(['group_id' => $id] + BizProjectFieldAuthModel::statusCondition()) : [];
        list($master_auth, $member_auth) = $this->optionsGenerate($fieldAuth);
        $response = [];
        foreach ($info as $v) {
            if ($v['group_id']) {
                $members[] = $v['admin_id'];
            } else {
                $response = [
                    'id' => $v['id'],
                    'responsible' => $v['responsible'],
                    'name' => $v['name'],
                    'email' => $v['email'],
                    'leader_id' => $v['admin_id'],
                    'member' => &$members,
                    'master_auth' => $master_auth,
                    'member_auth' => $member_auth,
                ];
            }
        }
        return $response;
    }

    private function error()
    {
        $fieldAuth = BizProjectGroup::fieldAuth($this->adminId(), 'admin');
        if (!$this->execForm($fieldAuth['project_auth'])) throw new Exception("权限不足");
    }
    /**
     * @throws Exception
     */
    public function save($input)
    {
        $this->error();
        $name = $input['name'] ?? '';
        $responsible = $input['responsible'] ?? '';
        if ($responsible === '') {
            $responsible = -1;
        }
        $leader_id = $input['leader_id'] ?? '';
        $email = $input['email'] ?? '';
        $member = $input['member'] ?? [];
        $member_auth = $input['member_auth'] ?? [];
        $master_auth = $input['master_auth'] ?? [];
        $id = $input['id'] ?? 0;
        if (empty($name)) throw new Exception("销售组名称 必须填写");
        if (empty($leader_id)) throw new Exception("leader 必须选择");
        if (empty($email)) throw new Exception("leader邮箱地址 必须填写");
        $old = BizProjectGroupModel::get('id', ['name' => $name] + BizProjectGroupModel::statusCondition());
        if ($old && $old != $id) throw new Exception("销售组名称 [{$name}] 已经存在");
        $data = compact('name','leader_id','email', 'member', 'responsible', 'member_auth', 'master_auth');
        BizProjectGroupModel::action(function () use ($id, $data) {
            $rs = BizProjectGroupModel::addData(['name' => $data['name'], 'responsible' => $data['responsible'], 'email' => $data['email'], 'admin_id' => $data['leader_id'], 'id' => $id]);
            if (!$rs) throw new \Exception('销售组信息保存失败');
            $group_id = $id ?: BizProjectGroupModel::id();
            $exists = BizProjectGroupModel::dataSelect(['group_id' => $group_id]);
            $existsMap = empty($exists) ? [] : array_column($exists, null, 'admin_id');
            $rows = [];
            foreach ($data['member'] as $member) {
                if (empty($member)) continue;
                if (isset($existsMap[$member])) {
                    $status = $existsMap[$member]['status'];
                    if (!BizProjectGroupModel::isNormal($status)) {
                        $rows[] = ['id' => $existsMap[$member]['id'], 'status' => BizProjectGroupModel::normalStatus()];
                    }
                    unset($existsMap[$member]);
                } else {
                    $rows[] = ['group_id' => $group_id, 'admin_id' => $member];
                }
            }
            foreach ($existsMap as $item) {
                $rows[] = ['id' => $item['id'], 'status' => BizProjectGroupModel::delStatus()];
            }
            foreach ($rows as $row) {
                BizProjectGroupModel::addData($row);
            }

            $exists = BizProjectFieldAuthModel::dataSelect(['group_id' => $group_id]);
            $existsMap = empty($exists) ? [] : array_column($exists, null, 'field_id');

            self::saveAuth($data['master_auth'], $data['member_auth'], $group_id, $existsMap);
        });

    }

    private function saveAuth($master_auth, $member_auth, $group_id, $existsMap)
    {
        //处理权限
        $master_auth = self::findAuthIdByName($master_auth);
        $member_auth = self::findAuthIdByName($member_auth);
        $rows = [];
        $fieldIds = array_unique(array_merge(array_keys($master_auth), array_keys($member_auth)));
        foreach ($fieldIds as $fieldId) {
            //如果存在就更新权限
            if (isset($existsMap[$fieldId])) {
                $rows[] = ['id' => $existsMap[$fieldId]['id'], 'master_auth' => $master_auth[$fieldId] ?? 0, 'member_auth' => $member_auth[$fieldId] ?? 0];
                unset($existsMap[$fieldId]);
            } else {
                $rows[] = ['group_id' => $group_id, 'field_id' => $fieldId, 'master_auth' => $master_auth[$fieldId] ?? 0, 'member_auth' => $member_auth[$fieldId] ?? 0];
            }
        }
        //删除未选择的
        foreach ($existsMap as $item) {
            $rows[] = ['id' => $item['id'], 'master_auth' => 0, 'member_auth' => 0];
        }
        //group_id field_id master_auth member_auth status
        foreach ($rows as $row) {
            BizProjectFieldAuthModel::addData($row);
        }

    }

    /**
     * @throws Exception
     */
    public function delete($id)
    {
        $this->error();
        return BizProjectGroupModel::statusDelete($id);
    }

    public function breadcrumb(): array
    {
        return [
            [
                'text' => BizProjectProject::getListTitle(), 'url' => BizProjectProject::getRoute()->getListRoute()
            ],
        ];
    }


    //extend auth
    public function optionsGenerate($fieldAuth): array
    {
        $master = [];
        $member = [];
        if (empty($fieldAuth)) return [$master, $member];
        //处理db数据
        $allFields = array_keys(self::$fields);
        foreach ($fieldAuth as $item) {
            $mode = $allFields[$item['field_id']];
            foreach (self::$score as $key => $v) {
                if ($item['master_auth'] & $v) $master[] = $mode . "." . $key;
                if ($item['member_auth'] & $v) $member[] = $mode . "." . $key;
            }
        }
        return [$master, $member];
    }

    public function optionsAuth(): array
    {
        $response = [];
        $i = 0;
        foreach (self::$fields as $field => $name) {
            $arr = explode(".", $field);
            if ($arr[0] == "admin" && $arr[1] != "project_process") {
                $response[$field . ".e"] = $name;
            } else {
                $response[$field . ".r"] = $name . "[查看]";
                $response[$field . ".w"] = $name . "[编辑]";
                $response[$field . ".e"] = $name . "[导出]";
            }
            $i++;
         }
        return $response;
    }
    public function findAuthIdByName($auth): array
    {
        $groupMode = [];
        foreach ($auth as $v) {
            $arr = explode(".", $v);
            if (count($arr) != 3) continue;
            $field = implode(".", [$arr[0], $arr[1]]);
            $mode = self::$score[$arr[2]] ?? 0;
            $groupMode[$field][] = $mode;
        }
        $idMap = array_flip(array_keys(self::$fields));
        $response = [];
        foreach ($groupMode as $field => $mode) {
            $response[$idMap[$field]] = array_sum($mode);
        }
        return $response;
    }
    public static function fieldAuth($adminId, $all = false): array
    {
        list($groupIds, $master) = BizProjectGroupModel::getGroupIdsByAdminId($adminId);
        $fieldAuth = $groupIds ? BizProjectFieldAuthModel::dataSelect(['group_id' => $groupIds] + BizProjectFieldAuthModel::statusCondition()) : [];
        $authFromDb = [];
        foreach ($fieldAuth as $v) {
            $old = $authFromDb[$v['field_id']] ?? 0;
            $add = in_array($v['group_id'], $master) ? $v['master_auth'] | $v['member_auth'] : $v['member_auth'];
            $authFromDb[$v['field_id']] = $old | $add;
        }

        // 1 查看 2 编辑 4 导出
        $response = [];
        $i = 0;
        foreach (self::$fields as $field => $name) {
            $group = explode(".", $field);
            $groupName = $group[0];
            $response[$groupName][$group[1] ?? $groupName] = $all === true ? (array_sum(self::$score)) : ($authFromDb[$i] ?? 0);
            $i++;
        }
        return is_string($all) ? $response[$all] : $response;
    }

    public static array $score = [
        'r' => 1,
        'w' => 2,
        'e' => 4,
    ];
    public static array $fields = [
        'responsible.seller' => '项目责任方-销售',
        'responsible.mcn' => '项目责任方-MCN',
        'responsible.planner' => '项目责任方-策划',
        'responsible.medium' => '项目责任方-媒介',
        'responsible.pm' => '项目责任方-PM',
        'responsible.finance' => '项目责任方-财务',
        'responsible.legal' => '项目责任方-法务',
        'customer.name' => '客户信息-品牌名称',
        'customer.category' => '客户信息-合作品类',
        'customer.product' => '客户信息-合作产品',
        'customer.type' => '客户信息-客户类型',
        'customer.area' => '客户信息-客户所属区域',
        'customer.area_code' => '客户信息-客户地理位置',
        'customer.intro' => '客户信息-客户基础信息',
        'customer.features' => '客户信息-客户特征',
        'customer.level' => '客户信息-客户分级',
        'project.type' => '项目信息-项目下单类型',
        'project.img' => '项目信息-客户明确合作意向沟通凭证',
        'project.no' => '项目信息-项目编号',
        'project.subject' => '项目信息-项目主体',
        'project.name' => '项目信息-项目名称',
        'project.money' => '项目信息-项目金额',
        'project.start_date' => '项目信息-项目周期(开始)',
        'project.company_type' => '项目信息-签约公司类型',
        'project.company_name' => '项目信息-签约公司名称',
        'project.company_contact' => '项目信息-签约公司对接方式',
        'project.rebate_rate' => '项目信息-返点比例（%）',
        'project.rebate' => '项目信息-返点金额',
        'project.external_link' => '项目信息-项目资料云盘链接',
        'project.contracts' => '项目信息-合作内容',
        'project.memo' => '项目信息-备注说明',
        'process.state' => '项目执行情况-项目状态',
        'process.end_date' => '项目执行情况-项目结案时间',
        'process.external_link' => '项目执行情况-项目结案云盘链接',
        'process.memo' => '项目执行情况-项目执行备注',
        'process.spot' => '项目执行情况-项目亮点',
        'process.problem' => '项目执行情况-项目问题',
        'process.solve' => '项目执行情况-项目问题解决方案',
        'process.advice' => '项目执行情况-后续建议',
        'process.consistent' => '项目执行情况-客户需求与交付是否一致',
        'process.consistent_memo' => '项目执行情况-客户需求与交付差异点',
        'process.different' => '项目执行情况-策划方案到执行落地交付差异性',
        'process.different_memo' => '项目执行情况-策划方案到执行落地交付差异点',
        'process.feedback' => '项目执行情况-项目满意度',
        'contract.create_time' => '合同签约信息-合同订立时间',
        'contract.archive_time' => '合同签约信息-合同归档时间',
        'contract.express_no' =>  '合同签约信息-合同邮寄快递单号',
        'contract.external_link' => '合同签约信息-合同链接',
        'contract.anticipated_initial' => '合同收款信息-预计首款收款金额',
        'contract.initial' => '合同收款信息-实际首款收款金额',
        'contract.anticipated_initial_time' => '合同收款信息-预计首款收款时间',
        'contract.initial_time' => '合同收款信息-实际首款收款时间',
        'contract.initial_bill_time' => '合同收款信息-首款开票时间',
        'contract.initial_bill_amount' => '合同收款信息-首款开票金额',
        'contract.initial_title' => '合同收款信息-首款发票号码',
        'contract.initial_express_no' => '合同收款信息-首款发票快递单号',
        'contract.anticipated_middle' => '合同收款信息-预计中款收款金额',
        'contract.middle' => '合同收款信息-实际中款收款金额',
        'contract.anticipated_middle_time' => '合同收款信息-预计中款收款时间',
        'contract.middle_time' => '合同收款信息-实际中款收款时间',
        'contract.middle_bill_time' => '合同收款信息-中款开票时间',
        'contract.middle_bill_amount' => '合同收款信息-中款开票金额',
        'contract.middle_title' => '合同收款信息-中款发票号码',
        'contract.middle_express_no' => '合同收款信息-中款发票快递单号',
        'contract.anticipated_tail' => '合同收款信息-预计尾款收款金额',
        'contract.tail' => '合同收款信息-实际尾款收款金额',
        'contract.anticipated_tail_time' => '合同收款信息-预计尾款收款时间',
        'contract.tail_time' => '合同收款信息-实际尾款收款时间',
        'contract.tail_bill_time' => '合同收款信息-尾款开票时间',
        'contract.tail_bill_amount' => '合同收款信息-尾款开票金额',
        'contract.tail_title' => '合同收款信息-尾款发票号码',
        'contract.tail_express_no' => '合同收款信息-尾款发票快递单号',
        'contract.memo' => '合同收款信息-收款情况备注',
        'contract.state_memo' => '合同收款信息-收款状态备注',
        'contract.other_data' => '合同收款信息-其它合同收款信息',
        'rebate.rebate' => '返点信息-返点信息',
        'costs.estimate' => '项目成本-成本预估金额',
        'costs.estimated_proportion' => '项目成本-成本预估占比（%）',
        'costs.real' => '项目成本-实际成本金额',
        'costs.real_proportion' => '项目成本-实际成本占比（%）',
        'costs.external_link' => '项目成本-项目成本云盘链接',
        'admin.project_delete' => '删除项目',
        'admin.project_auth' => '权限管理',
        'admin.project_process' => '项目跟进情况管理',
        'project.mcn' => '项目信息-是否需要达人合作',
        'mcn.mcn' => '达人合作',
        'pre.responsible' => '售前项目-项目责任方',
        'pre.base' => '售前项目-客户信息',
        'pre.intro' => '售前项目-项目简述及状态',
        'pre.plan' => '售前项目-策划方案',
        'pre.offer' => '售前项目-媒介报价',
        'admin.pre_delete' => '售前项目-删除',
    ];
}

